package org.aeon.service.impl;


import lombok.extern.slf4j.Slf4j;
import org.aeon.dao.ChatGroupDao;
import org.aeon.dao.UserDao;
import org.aeon.dao.UserGroupRelationDao;
import org.aeon.entity.ChatGroup;
import org.aeon.entity.dto.ChatGroupDto;
import org.aeon.entity.dto.GroupInfoDto;
import org.aeon.entity.dto.UserDto;
import org.aeon.service.ChatGroupService;
import org.aeon.utils.MybatisUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.modelmapper.ModelMapper;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class ChatGroupServiceImpl implements ChatGroupService {
    @Override
    public List<ChatGroupDto> getGroupsByUserId(Long userId) {
        try (SqlSession sqlSession = MybatisUtils.getSqlSession(true)) {
            final ChatGroupDao mapper = sqlSession.getMapper(ChatGroupDao.class);
            return mapper.getByUserId(userId);
        }
    }

    @Override
    public List<ChatGroupDto> getGroupsByIds(List<Long> groupIds) {
        SqlSession sqlSession = MybatisUtils.getSqlSession(false);
        try {
            final ChatGroupDao mapper = sqlSession.getMapper(ChatGroupDao.class);
            final List<ChatGroupDto> list = groupIds.stream()
                    .map(mapper::getById)
                    .map(group -> new ModelMapper().map(group, ChatGroupDto.class))
                    .toList();
            sqlSession.commit();
            sqlSession.clearCache();
            return list;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return new ArrayList<>();
    }

    @Override
    public Long getChatGroupId(String groupName) {
        try (SqlSession sqlSession = MybatisUtils.getSqlSession(true)) {
            final ChatGroupDao mapper = sqlSession.getMapper(ChatGroupDao.class);
            return mapper.getByName(groupName).getId();
        }
    }

    @Override
    public boolean isChatGroupExist(String groupName) {
        try (SqlSession sqlSession = MybatisUtils.getSqlSession(true)) {
            final ChatGroupDao mapper = sqlSession.getMapper(ChatGroupDao.class);
            final ChatGroup chatGroupByName = mapper.getByName(groupName);
            return chatGroupByName != null;
        }
    }

    @Override
    public boolean isChatGroupExist(Long groupId) {
        try (SqlSession sqlSession = MybatisUtils.getSqlSession(true)) {
            final ChatGroupDao mapper = sqlSession.getMapper(ChatGroupDao.class);
            final ChatGroup chatGroupByName = mapper.getById(groupId);
            return chatGroupByName != null;
        }
    }

    @Override
    public ChatGroup getChatGroup(String groupName) {
        try (SqlSession sqlSession = MybatisUtils.getSqlSession(true)) {
            final ChatGroupDao mapper = sqlSession.getMapper(ChatGroupDao.class);
            return mapper.getByName(groupName);
        }
    }

    @Override
    public ChatGroup getChatGroup(Long groupId) {
        try (SqlSession sqlSession = MybatisUtils.getSqlSession(true)) {
            final ChatGroupDao mapper = sqlSession.getMapper(ChatGroupDao.class);
            return mapper.getById(groupId);
        }
    }

    @Override
    public ChatGroup insertChatGroup(String groupName, Long userId) {
        try (SqlSession sqlSession = MybatisUtils.getSqlSession(true)) {
            final ChatGroupDao mapper = sqlSession.getMapper(ChatGroupDao.class);
            final ChatGroup chatGroup = new ChatGroup();
            chatGroup.setGroupName(groupName);
            chatGroup.setUserId(userId);
            chatGroup.setGroupDescription("还没有设置描述...");
            chatGroup.setCreationTime(new Date());
            mapper.insert(chatGroup);
            return chatGroup;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    @Override
    public int updateGroupNumberOfMembers(Long groupId, int number) {
        try (SqlSession sqlSession = MybatisUtils.getSqlSession(true)) {
            final ChatGroupDao mapper = sqlSession.getMapper(ChatGroupDao.class);
            return mapper.updatePeopleCount(groupId, number);
        }
    }

    @Override
    public boolean isCreator(Long groupId, Long userId) {
        try (SqlSession sqlSession = MybatisUtils.getSqlSession(true)) {
            final ChatGroupDao mapper = sqlSession.getMapper(ChatGroupDao.class);
            final ChatGroup group = mapper.getById(groupId);
            return Objects.equals(group.getUserId(), userId);
        }
    }

    @Override
    public int deleteGroup(Long groupId) {
        SqlSession sqlSession = MybatisUtils.getSqlSession(false);
        try {
            // 清理群聊关系
            final UserGroupRelationDao groupRelationDao = sqlSession.getMapper(UserGroupRelationDao.class);
            groupRelationDao.clean(groupId);
            // 删除群
            final ChatGroupDao groupDao = sqlSession.getMapper(ChatGroupDao.class);
            groupDao.delById(groupId);
            sqlSession.commit();
            sqlSession.clearCache();
            return 1;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            sqlSession.rollback();
            return -1;
        } finally {
            if (sqlSession != null)
                sqlSession.close();
        }
    }

    @Override
    public List<ChatGroupDto> fuzzySearch(String keyword) {
        try (SqlSession sqlSession = MybatisUtils.getSqlSession(true)) {
            final ChatGroupDao mapper = sqlSession.getMapper(ChatGroupDao.class);
            return mapper.getAll().stream()
                    .map(item -> new ModelMapper().map(item, ChatGroupDto.class))
                    .filter(item -> item.getGroupName().contains(keyword))
                    .toList();
        }
    }

    @Override
    public GroupInfoDto getChatGroupInfo(Long groupId) {
        List<Long> list;
        GroupInfoDto groupInfo;
        try (SqlSession sqlSession = MybatisUtils.getSqlSession(true)) {
            // 查询组
            final ChatGroupDao groupDao = sqlSession.getMapper(ChatGroupDao.class);
            final ChatGroup group = groupDao.getById(groupId);
            groupInfo = new ModelMapper().map(group, GroupInfoDto.class);

            // 查询成员
            final UserGroupRelationDao groupRelationDao = sqlSession.getMapper(UserGroupRelationDao.class);
            list = groupRelationDao.getMembers(groupId);
        }
        try (SqlSession sqlSession = MybatisUtils.getSqlSession(ExecutorType.BATCH, true)) {
            // 查询成员信息
            final UserDao mapper = sqlSession.getMapper(UserDao.class);
            final Set<UserDto> set = list.stream()
                    .map(item -> new ModelMapper().map(mapper.getById(item), UserDto.class))
                    .collect(Collectors.toSet());
            groupInfo.setMembers(set);
        }
        return groupInfo;
    }
}
